#nullable enable

using System;
using System.Collections.Generic;
using System.Linq;

namespace Lombiq.HelpfulLibraries.Common.Exceptions;

/// <summary>
/// 其消息可以安全地显示给桌面或命令行应用程序最终用户的异常。
/// </summary>
/// <remarks><para>
/// 对于 Web 应用程序，请使用 <c>Lombiq.HelpfulLibraries.AspNetCore</c> 的 <c>FrontendException</c>。
/// </para></remarks>
public class UserReadableException : Exception
{
    /// <summary>
    /// 获取可以显示给用户的错误消息列表。
    /// </summary>
    public IReadOnlyList<string> Messages { get; } = [];

    public UserReadableException(ICollection<string> messages, Exception? innerException = null)
        : base(string.Join(Environment.NewLine, messages), innerException) =>
        Messages = [.. messages];

    public UserReadableException(string message)
        : this([message])
    {
    }

    public UserReadableException()
    {
    }

    public UserReadableException(string message, Exception? innerException)
        : this([message], innerException)
    {
    }

    /// <summary>
    /// 如果提供的 <paramref name="errors"/> 集合不为空，则抛出包含相应文本的异常。
    /// </summary>
    /// <param name="errors">可能的错误文本集合。</param>
    /// <exception cref="UserReadableException"><paramref name="errors"/> 中的非空错误消息。</exception>
    public static void ThrowIfAny(ICollection<string>? errors)
    {
        errors = errors?.WhereNot(string.IsNullOrWhiteSpace).ToList();

        if (errors == null || errors.Count == 0) return;
        if (errors.Count == 1) throw new UserReadableException(errors.Single());

        throw new UserReadableException(errors);
    }
}
